package com.pzh.assignment.controller;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pzh.assignment.common.bean.GlobalConstant;
import com.pzh.assignment.common.bean.Result;
import com.pzh.assignment.common.bean.param.AccountParam;
import com.pzh.assignment.common.bean.param.PasswordParam;
import com.pzh.assignment.common.bean.param.UserInfoParam;
import com.pzh.assignment.common.bean.vo.AccountVO;
import com.pzh.assignment.common.bean.vo.RoleVO;
import com.pzh.assignment.common.bean.vo.UserVO;
import com.pzh.assignment.common.shiro.ShiroUtils;
import com.pzh.assignment.common.utils.SHA256Util;
import com.pzh.assignment.entity.Groups;
import com.pzh.assignment.entity.Role;
import com.pzh.assignment.entity.TaskFinal;
import com.pzh.assignment.entity.User;
import com.pzh.assignment.service.IGroupsService;
import com.pzh.assignment.service.IUserService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author pengzhihao
 * @since 2022-03-22
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    IUserService userService;
    @Autowired
    IGroupsService groupsService;

    @RequiresRoles(value = {"sys_admin", "super_admin", "org_admin"}, logical = Logical.OR)
    @GetMapping
    public Result listUserByPage(@RequestParam(defaultValue = "1") Integer currentPage,
                                 @RequestParam(defaultValue = "5") Integer size) {
        Page<User> page = new Page<>(currentPage, size);
        QueryWrapper<User> userQueryWrapper = initUserWrapper();
        IPage pageData = userService.page(page, userQueryWrapper);
        List<AccountVO> voList = ((IPage<User>)pageData).getRecords().stream().map(AccountVO::valueOf).collect(Collectors.toList());
        pageData.setRecords(voList);
        return Result.success(pageData);
    }

    @GetMapping("/total")
    public Result totalUser() {
        QueryWrapper<User> userQueryWrapper = initUserWrapper();
        List<User> users = userService.list(userQueryWrapper);
        List<AccountVO> voList = users.stream().map(AccountVO::valueOf).collect(Collectors.toList());
        return Result.success(voList);
    }

    @RequiresRoles(value = {"sys_admin", "super_admin", "org_admin"}, logical = Logical.OR)
    @PostMapping
    public Result saveOrUpdate(@RequestBody AccountParam param) {
        User user = new User();
        user.setUsername(param.getUsername());
        user.setAccount(param.getAccount());
        user.setRoleId(param.getRoleId());
        user.setGroupId(param.getGroupId());
        if (param.getId() != null) {
            //更新用户信息
            user.setId(param.getId());
            userService.saveOrUpdate(user);
        } else {
            //新增用户
            User tempUser = userService.getOne(new QueryWrapper<User>().eq("account", param.getAccount()));
            Assert.isNull(tempUser, "账号已存在！");
            // 设置默认密码
            user.setPassword(SHA256Util.getSHA256StrJava(GlobalConstant.DEFAULT_PASSWORD));
            userService.save(user);
        }
        return Result.success(null);
    }

    @RequiresRoles(value = {"sys_admin", "super_admin", "org_admin"}, logical = Logical.OR)
    @DeleteMapping
    public Result delete(@RequestParam Integer id) {
        userService.removeById(id);
        return Result.success(null);
    }

    @RequiresRoles(value = {"sys_admin", "super_admin", "org_admin"}, logical = Logical.OR)
    @GetMapping("/init-password")
    public Result resetPassword(@RequestParam Integer id){
        User user = userService.getById(id);
        // 设置默认密码
        user.setPassword(SHA256Util.getSHA256StrJava(GlobalConstant.DEFAULT_PASSWORD));
        userService.updateById(user);
        return Result.success(null);
    }

    @GetMapping("/byAccount")
    public Result findUser(@RequestParam String account) {
        User user = userService.getOne(new QueryWrapper<User>().eq("account", account));
        UserVO vo = UserVO.valueOf(user);
        Groups group = groupsService.getById(user.getGroupId());
        vo.setGroup(group.getName());
        return Result.success(vo);
    }

    @PostMapping("/password")
    public Result updatePassword(@RequestBody PasswordParam param) {
        Integer userId = ShiroUtils.getProfile().getId();
        User user = userService.getById(userId);
        Assert.isTrue(user.getPassword().equalsIgnoreCase(param.getOld()), "原密码错误");
        user.setPassword(param.getNow());
        userService.updateById(user);
        return Result.success(null);
    }

    @PostMapping("/info")
    public Result updateInfo(@RequestBody UserInfoParam param) {
        Integer userId = ShiroUtils.getProfile().getId();
        User user = userService.getById(userId);
        user.setPhone(param.getPhone());
        user.setEmail(param.getEmail());
        userService.updateById(user);
        return Result.success(null);
    }

    private QueryWrapper<User> initUserWrapper(){
        Role role = ShiroUtils.getProfile().getRole();
        Integer groupId = ShiroUtils.getProfile().getGroupId();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        switch (role.getName()) {
            case Role.SYSTEM_ADMIN:{
                wrapper.orderByDesc("create_time");
                break;
            }
            case Role.SUPER_ADMIN:{
                wrapper.ne("role_id", 1).orderByDesc("create_time");
                break;
            }
            case Role.ORG_ADMIN:{
                Groups group = groupsService.getById(groupId);
                List<Groups> groupsList = groupsService.list(new QueryWrapper<Groups>().eq("college_id", group.getCollegeId()));
                List<Integer> groupIds = groupsList.stream().map(groups -> groups.getId()).collect(Collectors.toList());
                wrapper.in("group_id", groupIds).notIn("role_id", 1, 2, 7).orderByDesc("create_time");
                break;
            }
            case Role.ADMIN:{
                wrapper.eq("group_id", groupId).orderByDesc("create_time");
                break;
            }
            case Role.TEACHER:{
                Integer teacherId = ShiroUtils.getProfile().getId();
                wrapper.eq("id", teacherId);
            }
        }
        return wrapper;
    }

}
